{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c1a5f1e6",
   "metadata": {},
   "source": [
    "# 基于施密特分解的分布式变分量子本征求解器\n",
    "\n",
    "*Copyright (c) 2021 Institute for Quantum Computing, Baidu Inc. All Rights Reserved.*"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cf44390c",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 概览\n",
    "\n",
    "在物理和化学等学科中，一个非常重要的问题就是提取分子、原子等物理系统的基态信息。系统的基态是由系统对应的哈密顿量决定的。目前普遍认为量子计算机在求解哈密顿量基态问题上具有优势。[变分量子本征求解器](https://qml.baidu.com/tutorials/quantum-simulation/variational-quantum-eigensolver.html)（variational quantum eigensolver, VQE），作为有望在近期展现量子优势的算法之一，为研究者们提供了可以在含噪的中等规模量子（NISQ）设备上研究量子化学的可能。然而，目前 NISQ 设备仍存在许多局限性，阻碍了大规模量子算法的运行。例如，受限于现有量子设备所能提供的量子比特数，研究者们无法利用 VQE 在 NISQ 设备上模拟真实的大分子。为了突破这一限制，许多分布式方案 [1-3] 相继被提出。\n",
    "在本教程中，我们以 [4] 提出的基于施密特分解的 VQE 为例，向读者展示如何利用 Paddle Quantum 实现分布式量子算法。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3fcc1b4",
   "metadata": {},
   "source": [
    "## 施密特分解\n",
    "\n",
    "对于任意处于复合系统 $AB$ 上的纯态 $|\\psi\\rangle$，我们有如下平凡分解:\n",
    "\n",
    "$$\n",
    "|\\psi\\rangle=\\sum_{ij}a_{ij}|i\\rangle\\otimes|j\\rangle,\n",
    "\\tag{1}\n",
    "$$\n",
    "\n",
    "其中 $|i\\rangle$ 和 $|j\\rangle$ 分别是子系统 $A$、$B$ 上的计算基底，$a_{ij}$ 是某复矩阵 $a$ 的元素。接下来，我们对矩阵 $a$ 运用[奇异值分解](https://zh.wikipedia.org/wiki/奇异值分解)（singular value decomposition, SVD），即，$a = udv$，其中 $u,v$ 是酉矩阵，$d$ 是对角矩阵。那么，$a_{ij}=\\sum_ku_{ik}d_{kk}v_{kj}$。\n",
    "\n",
    "通过定义 \n",
    "\n",
    "$$\n",
    "\\begin{aligned}\n",
    "|k_A\\rangle\\equiv & \\sum_iu_{ik}|i\\rangle=u|k\\rangle,\\\\\n",
    "|k_B\\rangle\\equiv & \\sum_jv_{kj}|j\\rangle=v^T|k\\rangle,\\\\\n",
    "\\lambda_k\\equiv & d_{kk},\\end{aligned}\n",
    "\\tag{2}\n",
    "$$\n",
    "\n",
    "我们可以把（1）式重写为\n",
    "\n",
    "$$\n",
    "\\begin{aligned}\n",
    "    |\\psi\\rangle  &= \\sum_{ijk}u_{ik}d_{kk}v_{kj}|i\\rangle\\otimes|j\\rangle \\\\\n",
    "                &= \\sum_{k}\\lambda_{k}\\Big(\\sum_iu_{ik}|i\\rangle\\Big)\\otimes\\Big(\\sum_jv_{kj}|j\\rangle\\Big) \\\\\n",
    "                &=\\sum_{k}\\lambda_k(u|k\\rangle\\otimes v^T|k\\rangle)\\\\\n",
    "                &=\\sum_{k}\\lambda_k|k_A\\rangle\\otimes|k_B\\rangle.\n",
    "\\end{aligned}\n",
    "\\tag{3}\n",
    "$$\n",
    "\n",
    "形如 $|\\psi\\rangle=\\sum_k\\lambda_k|k_A\\rangle\\otimes|k_B\\rangle$ 的分解方式就称为 **施密特分解**  [5]。同时，$\\{\\lambda_k\\}_k$ 被称作施密特系数，非零 $\\lambda_k$ 的数量被称为 $|\\psi\\rangle$ 的施密特秩。事实上，奇异值分解的性质还保证了 $\\lambda_k\\in\\mathbb{R}^+$ 及 $\\sum_k\\lambda_k^2=1$。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "620e053c",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 基于施密特分解的分布式 VQE\n",
    "\n",
    "作为标准 VQE [6] 的一个变种，分布式 VQE 同样试图寻找一个 $N$ 量子比特哈密顿量 $\\hat{H}=\\sum_tc_t\\hat{H}_t^{(A)}\\otimes\\hat{H}_t^{(B)}$ 的基态及其能量，其中 $\\hat{H}_t^{(A)},\\hat{H}_t^{(B)}$ 是分别作用于子系统 $A$、$B$ 上的哈密顿量分量（我们假设 $A$、$B$ 都包含 $N/2$ 量子比特）。\n",
    "\n",
    "我们从如下试探波函数开始：\n",
    "\n",
    "$$\n",
    "|\\psi\\rangle\\equiv\\sum_{k=1}^S\\lambda_k\\Big(U(\\boldsymbol{\\theta})|k\\rangle\\Big)\\otimes\\Big(V(\\boldsymbol{\\phi})|k\\rangle\\Big)\n",
    "\\tag{4},\n",
    "$$\n",
    "\n",
    "其中 $\\boldsymbol{\\lambda}\\equiv(\\lambda_1, \\lambda_2,...,\\lambda_S)^T$，$1\\leq S\\leq 2^{N/2}$ 是一个用户定义的常数。根据施密特分解，目标基态同样可写成（4）式的形式。因此，通过寻找合适的参数向量 $\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}$ 和 $\\boldsymbol{\\phi}$，我们可以在任意误差内近似目标基态。\n",
    "\n",
    "接下来，对于所有 $i,j=1,...,S$，我们在一台 $N/2$ 量子比特的量子计算机上计算如下项：\n",
    "\n",
    "$$\n",
    "\\begin{aligned}\n",
    "E_{ijt}^A(\\boldsymbol{\\theta}) &\\equiv \\langle i|U^\\dagger(\\boldsymbol{\\theta}) \\hat{H}_t^{(A)} U(\\boldsymbol{\\theta})|j\\rangle,\\\\\n",
    "E_{ijt}^B(\\boldsymbol{\\phi}) &\\equiv \\langle i|V^\\dagger(\\boldsymbol{\\phi}) \\hat{H}_t^{(B)} V(\\boldsymbol{\\phi}))|j\\rangle.\n",
    "\\end{aligned}\n",
    "\\tag{5}\n",
    "$$\n",
    "\n",
    "然后，在一台经典计算机上，我们根据如下定义构造一个 $S\\times S$ 维的矩阵 $M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$：\n",
    "\n",
    "$$\n",
    "[M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})]_{ij}\\equiv\\sum_tc_tE_{ijt}^A(\\boldsymbol{\\theta})E_{ijt}^B(\\boldsymbol{\\phi}).\n",
    "\\tag{6}\n",
    "$$\n",
    "\n",
    "这样，目标基态能量就可以写为 \n",
    "\n",
    "$$\n",
    "\\begin{aligned}\n",
    "E_{tar}   &= \\min_{\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}, \\boldsymbol{\\phi}} \\langle{\\psi}|\\hat{H}|\\psi\\rangle \\\\\n",
    "    &= \\min_{\\boldsymbol{\\lambda}, \\boldsymbol{\\theta}, \\boldsymbol{\\phi}}\\Big(\\sum_{i,j=1}^S\\lambda_i\\lambda_j[M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})]_{ij}\\Big)\\\\\n",
    "    &= \\min_{\\boldsymbol{\\theta}, \\boldsymbol{\\phi}} E(\\boldsymbol{\\theta},\\boldsymbol{\\phi}),\n",
    "\\end{aligned}\n",
    "\\tag{7}\n",
    "$$\n",
    "\n",
    "其中 $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})\\equiv\\min_{\\boldsymbol{\\lambda}} \\boldsymbol{\\lambda}^T M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})\\boldsymbol{\\lambda}$。根据线性代数的内容，不难发现，$E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ 正是矩阵 $M(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$ 的最小特征值，可以通过经典算法求得。\n",
    "\n",
    "最终，我们重复如上过程，并使用基于梯度下降的优化方法最小化 $E(\\boldsymbol{\\theta},\\boldsymbol{\\phi})$，使其趋近于 $E_{tar}$。\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f79d3333",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 量桨实现\n",
    "\n",
    "首先，我们导入必要的包。由于我们要使用飞桨和量桨的最新功能，请确保您的 *PaddlePaddle* >= 2.2.0 且 *Paddle Quantum* >= 2.2.0。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bb7c0db4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "import paddle\n",
    "import paddle_quantum\n",
    "from paddle_quantum.ansatz import Circuit\n",
    "from paddle_quantum.qinfo import pauli_str_to_matrix, schmidt_decompose\n",
    "import warnings\n",
    "\n",
    "warnings.filterwarnings(\"ignore\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c84dd264",
   "metadata": {},
   "source": [
    "定义一些全局常数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "27e4ce36",
   "metadata": {},
   "outputs": [],
   "source": [
    "N = 10      # 量子比特数\n",
    "SEED = 16   # 固定随机种子\n",
    "ITR = 100   # 设置迭代次数\n",
    "LR = 0.1    # 设置学习率\n",
    "D = 3       # 设置量子神经网络的层数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3db38f56",
   "metadata": {},
   "source": [
    "下面这一函数经典地计算出哈密顿量 $H$ 的基态信息（基态对能量和施密特秩），以作为后面量子模型的基准参照。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "32b310ed",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_ground_state_info(H):\n",
    "\n",
    "    # 计算 H 的特征值与特征向量\n",
    "    vals, vecs = paddle.linalg.eigh(H)\n",
    "    # 获取基态\n",
    "    ground_state = paddle_quantum.State(vecs[:, 0])\n",
    "    # 获取基态能量\n",
    "    ground_state_energy = vals.tolist()[0]\n",
    "    print(f'The ground state energy is {ground_state_energy:.5f} Ha.')\n",
    "    # 对基态运用施密特分解\n",
    "    l, _, _ = schmidt_decompose(ground_state)\n",
    "    print(f'Schmidt rank of the ground state is {l.size}.')\n",
    "\n",
    "    return ground_state_energy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c2c88d3",
   "metadata": {},
   "source": [
    "现在，我们生成一个哈密顿量并计算其基态信息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6149b4d4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The ground state energy is -0.99783 Ha.\n",
      "Schmidt rank of the ground state is 3.\n"
     ]
    }
   ],
   "source": [
    "# 固定随机种子\n",
    "np.random.seed(SEED)\n",
    "\n",
    "# 硬编码一个哈密顿量\n",
    "coefs = [-0.8886258, 0.453882]\n",
    "pauli_str = ['x0,z1,z2,z4,x5,y6,y7,x8,x9', 'y0,x1,x2,x3,y4,x5,z6,z7,y8,x9']\n",
    "pauli_str_A = ['x0,z1,z2,z4', 'y0,x1,x2,x3,y4']     # 子系统 A 的泡利字符串\n",
    "pauli_str_B = ['x0,y1,y2,x3,x4', 'x0,z1,z2,y3,x4']  # 子系统 B 的泡利字符串\n",
    "\n",
    "# 把相关对象转换为张量形式\n",
    "H_mtr = paddle.to_tensor(pauli_str_to_matrix(zip(coefs, pauli_str), n=N))\n",
    "coefs = paddle.to_tensor(coefs)\n",
    "H_A = [pauli_str_to_matrix([[1., pstr]], n=N//2) for pstr in pauli_str_A]\n",
    "H_A = paddle.to_tensor(np.stack(H_A))\n",
    "H_B = [pauli_str_to_matrix([[1., pstr]], n=N-N//2) for pstr in pauli_str_B]\n",
    "H_B = paddle.to_tensor(np.stack(H_B))\n",
    "\n",
    "# 计算该哈密顿量的基态信息\n",
    "ground_state_energy = get_ground_state_info(H_mtr)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9abf331c",
   "metadata": {},
   "source": [
    "准备好一个哈密顿量后，我们可以构建一个分布式 VQE 来求解它。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "32cacc67",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造参数化量子电路\n",
    "def U_cir(N, D):\n",
    "    \n",
    "    cir = Circuit(N)  # 初始化一个宽度为 N 量子比特的电路\n",
    "    cir.complex_entangled_layer('full', N, D)  # 添加量子门\n",
    "    return cir  \n",
    "\n",
    "# 把参数化电路作用在计算基底上\n",
    "# 并返回一个形状为 [2**N, num_states] 的张量\n",
    "def output_states(num_states, N, cir):\n",
    "    # 创建 num_states 个计算基底\n",
    "    basis = paddle.eye(2**N, num_states)\n",
    "\n",
    "    # 获取参数化电路的矩阵\n",
    "    U = cir.unitary_matrix()\n",
    "    \n",
    "    # 把参数化电路作用在这些基底上\n",
    "    vec = U @ basis                         \n",
    "    \n",
    "    return vec"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ca5787c",
   "metadata": {},
   "source": [
    "以下代码是本教程的核心。请读者仔细阅读，并与前文的公式叙述做比较。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "6ebf5159",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 构造分布式模型\n",
    "class DistributedVQE(paddle.nn.Layer):\n",
    "    def __init__(self, N, D, S):\n",
    "        super().__init__()\n",
    "        paddle.seed(SEED)\n",
    "\n",
    "        self.S = S  # 定义常数 S\n",
    "        self.N = N\n",
    "        self.cir = [U_cir(N//2, D), U_cir(N - N//2, D)]\n",
    "        \n",
    "    # 分布式 VQE 的核心逻辑\n",
    "    def forward(self):\n",
    "        # 分别获得子系统 A、B 上的 U|k> 和 V|k> \n",
    "        vec_A = output_states(self.S, self.N//2, self.cir[0])\n",
    "        vec_B = output_states(self.S, self.N - self.N//2, self.cir[1])\n",
    "        \n",
    "        # 计算由前文定义的 E_{ijt}^A 和 E_{ijt}^B 组成的张量 E_A, E_B\n",
    "        E_A = vec_A.conj().t() @ H_A @ vec_A\n",
    "        E_B = vec_B.conj().t() @ H_B @ vec_B\n",
    "        M = (coefs.reshape([-1, 1, 1]) * E_A * E_B).sum(0)\n",
    "\n",
    "        # 计算矩阵 M 的最小特征值\n",
    "        eigval = paddle.linalg.eigvalsh(M)\n",
    "        loss = eigval[0]\n",
    "        \n",
    "        return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d04669ff",
   "metadata": {},
   "source": [
    "定义训练函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "066f5e72",
   "metadata": {},
   "outputs": [],
   "source": [
    "def train(model):\n",
    "    start_time = time.time()    # 用以计算该函数的运行时长\n",
    "    params = sum([cir.parameters() for cir in model.cir], [])\n",
    "    # 我们使用基于梯度下降的优化器 Adam 来优化 theta 和 phi\n",
    "    opt = paddle.optimizer.Adam(learning_rate=LR, parameters=params)\n",
    "    summary_loss = []           # 记录损失历史\n",
    "\n",
    "    # 迭代优化\n",
    "    for itr in range(ITR):\n",
    "        # 前向传播，计算损失函数\n",
    "        loss = model()\n",
    "        # 后向传播，优化损失函数\n",
    "        loss.backward()\n",
    "        opt.minimize(loss)\n",
    "        opt.clear_grad()\n",
    "        # 更新优化结果\n",
    "        summary_loss.append(loss.numpy())\n",
    "        # 打印中间结果\n",
    "        if (itr+1) % 20 == 0:\n",
    "            print(f\"iter: {itr+1}, loss: {loss.tolist()[0]: .4f} Ha\")\n",
    "\n",
    "    print(f'Ground truth is  {ground_state_energy:.4f} Ha')\n",
    "    print(f'Training took {time.time() - start_time:.2f}s')\n",
    "    \n",
    "    plt.plot(list(range(ITR)), summary_loss, color='r', label='loss')\n",
    "    plt.hlines(y=ground_state_energy, xmin=0, xmax=ITR, linestyle=':',  label='ground truth')\n",
    "    plt.legend()\n",
    "    plt.title(f'Loss for {type(model).__name__} on a {N}-qubit Hamiltonian')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c8770b19",
   "metadata": {},
   "source": [
    "现在，我们实例化并训练分布式模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "78b46dcc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter: 20, loss: -0.9244 Ha\n",
      "iter: 40, loss: -0.9906 Ha\n",
      "iter: 60, loss: -0.9968 Ha\n",
      "iter: 80, loss: -0.9977 Ha\n",
      "iter: 100, loss: -0.9978 Ha\n",
      "Ground truth is  -0.9978 Ha\n",
      "Training took 11.81s\n"
     ]
    },
    {
     "data": {
      "image/png": "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BYTn7/8Ir/8phI3QO4p8pop2O9CH0Nf+EgU2LhfiL4T37WjCzgZbifqSo37rywlBtJoQLgU3CBac12uE12p2IW3fStjL5duozicLmUdR74F87r4FuAv4f9Fr3r+YZSzKtYT3wsao9sK+XMpD3p8j15lZ3rau0YQ9k1YAzwK3RduaSquylqFELGyPFEldZnYRIcCOjbqDhPAHKcKXYc2y/NqU6qdK/sFGpDy5+1/NbCdhrxoFvqQtreGLpCmt4acfBb6ISJpIh422IiJCFe/Db968ubdr1y7uMkREqo1Zs2atdfcWhY2r0oHfrl07cnJy4i5DRKTaMLMi/0GtLh0RkTShwBcRSRMKfBGRNFGl+/BFpOrZuXMny5YtY9u2bXGXktaysrJo06YNNWvWLH7iiAJfREpl2bJlNGjQgHbt2hGOMSiVzd1Zt24dy5Yto3379iV+nLp0RKRUtm3bRrNmzRT2MTIzmjVrVupfWQp8ESk1hX38yvIapF7g79wJEybA60UdNVhEJD2lXuBnZsI998Azz8RdiYhUkPr1K+wsgCkt9QLfDLp3h7lz465ERKRKSb3Ah72BryOBiqQ0d+e6666je/fu9OjRg6eeCieUWrlyJQMHDqRXr150796dadOmsXv3bsaOHZs/7e9+97uYq698qblbZvfusGEDLF0KbQuep1lEys0vfgG5ueU7z1694Pe/L9GkkydPJjc3l48++oi1a9dy5JFHMnDgQJ588klOPPFEbr75Znbv3s2WLVvIzc1l+fLlzI1+/a9fv758664GUnMNv0ePcK1uHZGU9u677zJ69GgyMjI44IADOP7445k5cyZHHnkkjzzyCOPGjWPOnDk0aNCADh068MUXX3DllVfy6quv0rBhw7jLr3SpuYZ/2GHheu5cGD483lpEUlkJ18QrSlEncBo4cCDvvPMOL730Eueffz7XXXcdF1xwAR999BGvvfYa999/P08//TR//etfK7nieKXmGn6TJtC6tdbwRVLcwIEDeeqpp9i9ezdr1qzhnXfeoV+/fixZsoSWLVtyySWXcPHFFzN79mzWrl3Lnj17OOOMM7jjjjuYPXt23OVXutRcwwftqSOSBk477TRmzJhBz549MTPuvvtufvCDH/Doo49yzz33ULNmTerXr89jjz3G8uXLufDCC9mzZw8A48ePj7n6ylelz2nbt29fL/MJUK69Fv74R9i0KeybLyLlYt68eXTr1i3uMoTCXwszm+XufQubPjW7dCBsuN2+HT7/PO5KRESqhNQN/O7dw7W6dUREgFQO/G7dwr9uFfgiIkAqB37dutCxowJfRCSSuoEPoR9/zpy4qxARqRJSO/C7d4eFC0GnYhMRSYPA37MH5s+PuxIRSSHjxo3jN7/5zffuf+655/j0009LPb/Fixfz5JNP5g//7W9/42c/+1lSNRYm9QMf1I8vkoZ27dpV6W3uL/D3V0/BwK8oqR34nTpBrVrqxxdJMXfccQddu3Zl6NChjB49On9te9CgQdx0000cf/zx3HfffUydOpXevXvTo0cPLrroIrZv3w5Au3btWLt2LQA5OTkMGjQICGvuF110EYMGDaJDhw784Q9/yG/zrrvuokuXLgwZMoQFCxZ8r6bp06czZcoUrrvuOnr16sXnn3/+vXrGjh3LpEmT8h+TdyKXG264gWnTptGrV6/8wzavWLGCYcOG0alTJ66//vpyed5SO/Br1oTOnWHevLgrEUlZox6Ywb9ylgKwc/ceRj0wg2c/XAbA1h27GfXADF74aAUAG7btZNQDM3h17koAvtm8g1EPzODNT1cBsHpj8dvbcnJyeOaZZ/jwww+ZPHkyBf+Nv379et5++22uuOIKxo4dy1NPPcWcOXPYtWsXf/7zn4ud//z583nttdf44IMPuP3229m5cyezZs3in//8Z36bM2fO/N7jjjnmGEaMGME999xDbm4uHTt23Keea665psg2J0yYwIABA8jNzeXqq68GIDc3N7/2p556iqVLlxZbe3FSO/ABunZV4IukkHfffZeRI0dSp04dGjRowCmnnLLP+FGjRgGwYMEC2rdvT+fOnQEYM2YM77zzTrHzP+mkk6hduzbNmzenZcuWrFq1imnTpnHaaadRt25dGjZsyIgRI0pcb149pTV48GAaNWpEVlYWhx56KEuWLCnTfBKl/kFmunWDyZPDYRZq1467GpGU89RlR+ffrplRY5/hOrUy9hlumFVzn+Gm9WrtM9yyQVax7RV3/K969eoVO11mZmb+QdS2FdiLr3ZCTmRkZOT3vZtZsbXtr56C7bo7O3bsKPJxRdWRjPRYw9+zJ+yeKSLV3nHHHccLL7zAtm3b2LRpEy+99FKh03Xt2pXFixezaNEiAB5//HGOP/54IPThz5o1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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 注意，由于我们构造的哈密顿量在两子系统间相互作用较小，我们只需设置 S = 4.\n",
    "#（更多解释请见总结部分）\n",
    "vqe = DistributedVQE(N, D, S=4)\n",
    "train(vqe)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9eb85055",
   "metadata": {},
   "source": [
    "在上图中，我们用虚线画出了真实的基态能量。可以看到，loss 曲线收敛至虚线，表明我们的分布式 VQE 成功找到了该哈密顿量的基态能量。然而，要妥当地评估我们的模型，我们还需将它与标准 VQE 做比较。因此，下面我们构建标准 VQE 模型："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "2fff9166",
   "metadata": {},
   "outputs": [],
   "source": [
    "class StandardVQE(paddle.nn.Layer):\n",
    "    def __init__(self, N, D, S):\n",
    "        super().__init__()\n",
    "        paddle.seed(SEED)\n",
    "        self.N = N\n",
    "        self.S = S\n",
    "        self.cir = [U_cir(N, D)]\n",
    "      \n",
    "    def forward(self):\n",
    "        vec = output_states(self.S, self.N, self.cir[0])\n",
    "        loss = vec.conj().t() @ H_mtr @ vec\n",
    "        return loss.cast('float64').flatten()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bc5dcfd",
   "metadata": {},
   "source": [
    "实例化并训练标准 VQE。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "a35f3eb4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter: 20, loss: -0.8365 Ha\n",
      "iter: 40, loss: -0.9852 Ha\n",
      "iter: 60, loss: -0.9958 Ha\n",
      "iter: 80, loss: -0.9975 Ha\n",
      "iter: 100, loss: -0.9978 Ha\n",
      "Ground truth is  -0.9978 Ha\n",
      "Training took 2252.27s\n"
     ]
    },
    {
     "data": {
      "image/png": "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ls6ECbBtG/xFh/2LpKPBgwczffp0du7cSWlpKa+88goDBw5kxYoVdOjQgfPPP5/zzjuP+fPns2bNGnbt2sVpp53GDTfcwPz581Mdfr1L76EVevWCQYPguedCK19E0sopp5zC3Llz6devH2bGjTfeSKdOnZg2bRo33XQTDRs2pHnz5tx///2sXLmSc845h127dgEwefLkFEdf//bqa9oWFhZ60hdAufpquPFGWLcOdOyuSNIWLVrEQQcdlOowhPifhZnNc/fCePOnd5cOwJAhsHMnzJmT6khERFIq/RP+oEGQlQWvvJLqSEREUir9E35uLgwYoLF1RCTjpX/Ch9Ct8+absGVLqiMREUmZzEn427bBG2+kOhIRkZTJjIR/1FFhFE1164hIBsuMhN+qFfTrpx23IlIrJk2axM1xhm3517/+xfvvv1/j5S1fvpwHH3ywvHzfffdx0UUXJRVjPJmR8AEGD4a5c0PXjoikvR07dtT7OqtK+FXFUzHh15XMSfhDhoSdthojX2Sfd8MNN3DggQdyzDHHMGbMmPLW9tChQ7n66qsZMmQIt99+O7Nnz+awww7jkEMO4dxzz+Wbb74BIC8vjzVr1gBQXFzM0KFDgdByP/fccxk6dCgFBQX86U9/Kl/n7373O3r37s3w4cP54IMPvhPTnDlzmDVrFldccQX9+/dn2bJl34ln3LhxPPLII+WvKbuQy8SJE3n11Vfp379/+bDNn332Gccddxy9evXiyiuvrJX3LXMS/tFHh3v144vUqlF3zuWfxeGCdtt37mLUnXN57O0SALZs28moO+fyxDvh8hcbtm5n1J1zeXZhGB39y6+3MerOubzw/moAvthY/UW5i4uLefTRR3n77beZOXMmFc/GX7duHS+//DIXXngh48aNY/r06bz77rvs2LGDvyQwrtbixYt57rnnePPNN7nuuuvYvn078+bN4+GHHy5f51tvvfWd1w0aNIiTTjqJm266iQULFtCzZ8/d4pkwYUKl65wyZQpHH300CxYs4PLLLwdgwYIF5bFPnz6dTz/9tNLXJypzEn779rD//jBvXqojEZEkvPbaa4wcOZImTZqQm5vLT37yk92mjxo1CoAPPviA/Px8DjjgAADGjh3LKwnsxzvhhBNo3Lgx7dq1o0OHDqxevZpXX32VU045haZNm9KiRQtOOumkhOMti6emhg0b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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "svqe = StandardVQE(N, D, S=1)\n",
    "train(svqe)  # 训练标准 VQE"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5688a618",
   "metadata": {},
   "source": [
    "有趣的是，通过比较两个模型的运行时间，我们发现，分布式 VQE 的运行速度比标准 VQE 快了一百多倍！事实上，这很容易理解：在分布式模型中，我们只需模拟两个 $N/2$ 量子比特的酉变换，这无论在时间还是空间上，都比标准 VQE 中模拟一个 $N$ 量子比特的酉变换高效得多。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "94cda668",
   "metadata": {
    "tags": []
   },
   "source": [
    "## 总结\n",
    "\n",
    "在此教程中，我们构造了一个分布式 VQE 并展示了其部分优势：\n",
    "- NISQ 设备的计算范围得以拓展。通过分布式策略，我们可以运行超过硬件量子比特数的量子算法。\n",
    "- 计算效率得到提升。对于量子过程的经典模拟而言，分布式算法降低了酉矩阵的维度，因此降低了模拟这些矩阵所需的时间、空间消耗。\n",
    "\n",
    "同时，需要注意的是，用户定义的常数 $S$ 在训练准确度和效率上扮演了重要角色：\n",
    "- 对于子系统间相互作用弱的哈密顿量而言，其基态在子系统间纠缠较弱 [7]。因此，其施密特秩较低，可以被一个较小的 $S$ 精确且高效地模拟。事实上，我们所给的演示及大多数物理、化学中有意义的哈密顿量都具有此性质。\n",
    "- 相反的，对于子系统间相互作用强的哈密顿量而言，其基态在子系统间纠缠较强，因此需要一个较大的 $S$ 来模拟。但是，无论如何，$S$ 的上界是 $2^{N/2}$，因此矩阵 $M$ 的维度上界是 $2^{N/2}\\times2^{N/2}$，这仍然比初始哈密顿量的维度（$2^{N}\\times 2^{N}$）小。因此，该算法的效率总是优于纯经典模拟。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "922679aa",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "_______\n",
    "\n",
    "# 参考文献\n",
    "\n",
    "[1] Fujii, Keisuke, et al. \"Deep Variational Quantum Eigensolver: a divide-and-conquer method for solving a larger problem with smaller size quantum computers.\" [arXiv preprint arXiv:2007.10917 (2020)](https://arxiv.org/abs/2007.10917).\n",
    "\n",
    "[2] Zhang, Yu, et al. \"Variational Quantum Eigensolver with Reduced Circuit Complexity.\" [arXiv preprint arXiv:2106.07619 (2021)](https://arxiv.org/abs/2106.07619).\n",
    "\n",
    "[3] Peng, Tianyi et al. \"Simulating Large Quantum Circuits On A Small Quantum Computer\". [Physical Review Letters 125.15, (2020): 150504](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.125.150504).\n",
    "\n",
    "[4] Eddins, Andrew, et al. \"Doubling the size of quantum simulators by entanglement forging.\" [arXiv preprint arXiv:2104.10220 (2021)](https://arxiv.org/abs/2104.10220).\n",
    "\n",
    "[5] Nielsen, Michael A., and Isaac L. Chuang. Quantum Computation and Quantum Information. Cambridge University Press, 2010.\n",
    "\n",
    "[6] Moll, Nikolaj, et al. \"Quantum optimization using variational algorithms on near-term quantum devices.\" [Quantum Science and Technology 3.3 (2018): 030503](https://iopscience.iop.org/article/10.1088/2058-9565/aab822).\n",
    "\n",
    "[7] Khatri, Sumeet, and Mark M. Wilde. \"Principles of quantum communication theory: A modern approach.\" [arXiv preprint arXiv:2011.04672 (2020)](https://arxiv.org/abs/2011.04672)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
